package com.ruoyi.web.controller.PhoneLogin;

import com.ruoyi.system.service.PhoneLoginService;
import com.ruoyi.system.util.HttpsUtil;
import com.ruoyi.system.util.StringUtil;

import net.sf.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.ruoyi.common.config.Global.getConfig;

@Controller
@RequestMapping(value = "/a/data")
public class WeChatJSSDKController {

    @Autowired
    private PhoneLoginService phoneLoginService;

    private  String appids=getConfig("weixin4j.appids");

    private  String appsecret=getConfig("weixin4j.secrets");

    private  String mch_id=getConfig("weixin4j.mch_id");

    private  String MerchantKey=getConfig("weixin4j.MerchantKey");
    public  String getAccessToken() throws Exception{
        String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
                +appids+ "&secret="+appsecret;
        System.out.println("URL for getting accessToken accessTokenUrl="+accessTokenUrl);

        URL url = new URL(accessTokenUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        connection.setRequestMethod("GET");
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.connect();

        //获取返回的字符
        InputStream inputStream = connection.getInputStream();
        int size =inputStream.available();
        byte[] bs =new byte[size];
        inputStream.read(bs);
        String message=new String(bs,"UTF-8");

        //获取access_token
        JSONObject jsonObject = JSONObject.fromObject(message);
        String accessToken = jsonObject.getString("access_token");
        String expires_in = jsonObject.getString("expires_in");
        System.out.println("accessToken="+accessToken);
        System.out.println("expires_in="+expires_in);
        return accessToken;
    }


    public static void main(String[] args){

        try {
            //System.out.println(WeChatJSSDKController.getAccessToken());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private  String urls=getConfig("weixin4j.hddz");


    public Map<String, Object> zf1(Integer jes,String order_id,String uid,HttpServletRequest request, HttpServletResponse response,String lx){

        HttpSession session= request.getSession();
        String openid = phoneLoginService.CallShellProcedure("R2006004|"+uid).get(0).get("openid").toString();
        System.err.println("openid=========="+openid);
        //oWbqL1T3O975WcrubVVpxcKVv7CU
        Date currentTime = new Date();

        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");

        String s8 = formatter.format(currentTime);

        System.out.println(openid);
        Map<String, Object> returnMap=new HashMap<String, Object>();
        String appId =appids;
        String body = "校园帮帮支付";
        String merchantId = mch_id;
        if(order_id.equals("0")){
            order_id="ZF"+s8+((int)((Math.random()*9+1)*100000));
        }
        String tradeNo =order_id+lx;
        //String tradeNo ="ZF"+s8+((int)((Math.random()*9+1)*100000))+lx;
        String nonceStr1 = createNonceStr();
        String notifyUrl = urls;
        String openId = openid;
        String totalFee = Integer.toString(jes);
        System.err.println("totalFee===================hah"+totalFee);


        TreeMap<String, String> map = new TreeMap<String, String>();
        //TreeMap<Object, Object> map = new TreeMap<Object, Object>();
        map.put("appid", appId);
        map.put("mch_id", merchantId);
        map.put("device_info", "WEB");
        map.put("body", body);
        map.put("trade_type", "JSAPI");
        map.put("nonce_str", nonceStr1);
        map.put("notify_url", notifyUrl);
        map.put("out_trade_no", tradeNo);
        map.put("total_fee", totalFee);
        map.put("openid", openId);
        String sign = createSign(map);


        String xml = "<xml>" +
                "<appid>" + appId + "</appid>" +
                "<body>" + body +"</body>" +
                "<device_info>WEB</device_info>" +
                "<mch_id>" + merchantId + "</mch_id>" +
                "<nonce_str>" + nonceStr1 + "</nonce_str>" +
                "<notify_url>" + notifyUrl +"</notify_url>" +
                "<openid>" + openId + "</openid>" +
                "<out_trade_no>" + tradeNo + "</out_trade_no>" +
                "<total_fee>" + totalFee + "</total_fee>" +
                "<trade_type>JSAPI</trade_type>" +
                "<sign>" + sign + "</sign>" +
                "</xml>";
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

        String result = null;

        result = HttpsUtil.httpsRequestToString(url, "POST", xml);


        String reg = "<prepay_id><!\\[CDATA\\[(\\w+)\\]\\]></prepay_id>";

        Pattern pattern = Pattern.compile(reg);
        System.out.println(result);
        Matcher matcher = pattern.matcher(result);

        String prepayId = "";

        while (matcher.find()) {

            prepayId = matcher.group(1);

            System.out.println("预支付ID：" + prepayId);
        }
        Date beijingDate = Calendar.getInstance(Locale.CHINA).getTime();
        String  datassss=String.valueOf(beijingDate.getTime() / 1000);
        String  nonceStrss =createNonceStr();
        //appId, timeStamp, nonceStr, package, signType
        //paySign=MD5(appId=${appid}&nonceStr=${nonceStr}&package=prepay_id=${prepay_id}&signType=MD5&timeStamp=${timeStamp}&key=${key}).toString().toUpperCase();
        String stringAs="appId="+appids+"&nonceStr="+nonceStrss+"&package=prepay_id="+prepayId+"&signType=MD5&timeStamp="+datassss+"&key="+MerchantKey;
        System.out.println(stringAs);
        String dd = null;
        try {
            dd = MD5(stringAs).toUpperCase();
        } catch (Exception e) {
            e.printStackTrace();
        }
        List<Map<String, Object>> list =  phoneLoginService.CallShellProcedure("R2009006|"+openId+"|"+datassss+"|"+jes+"|"+tradeNo);

        returnMap.put("paySignss",dd);
        returnMap.put("appids",appids);
        returnMap.put("timestampss", datassss);
        returnMap.put("nonceStrss", nonceStrss);
        returnMap.put("packagess", "prepay_id=" + prepayId);
        returnMap.put("signTypess", "MD5");
        returnMap.put("tradeNo", tradeNo);

        return returnMap;
    }
   // @RequestMapping(value="/zf1")
   // @ResponseBody
   /* public Map<String, Object> zf1(String jes, String urls,String uid,
                                   HttpServletRequest request, HttpServletResponse response){
        HttpSession session= request.getSession();
        String openid = phoneLoginService.CallShellProcedure("R2006004|"+uid).get(0).get("openid").toString();

        Map<String, Object> returnMap=new HashMap<String, Object>();
        String appId =appids;
        String body = "校园帮帮支付";
        String merchantId = mch_id;
        String tradeNo = String.valueOf(new Date().getTime());
        String nonceStr1 = createNonceStr();
        String notifyUrl = urls;
        String openId = openid;
        String totalFee = jes;


        TreeMap<String, String> map = new TreeMap<String, String>();
        map.put("appid", appId);
        map.put("mch_id", merchantId);
        map.put("device_info", "WEB");
        map.put("body", body);
        map.put("trade_type", "JSAPI");
        map.put("nonce_str", nonceStr1);
        map.put("notify_url", notifyUrl);
        map.put("out_trade_no", tradeNo);
        map.put("total_fee", totalFee);
        map.put("openid", openId);
        String sign = createSign(map);


        String xml = "<xml>" +
        "<appid>" + appId + "</appid>" +
        "<body>" + body +"</body>" +
        "<device_info>WEB</device_info>" +
        "<mch_id>" + merchantId + "</mch_id>" +
        "<nonce_str>" + nonceStr1 + "</nonce_str>" +
        "<notify_url>" + notifyUrl +"</notify_url>" +
        "<openid>" + openId + "</openid>" +
        "<out_trade_no>" + tradeNo + "</out_trade_no>" +
        "<total_fee>" + totalFee + "</total_fee>" +
        "<trade_type>JSAPI</trade_type>" +
        "<sign>" + sign + "</sign>" +
        "</xml>";
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

        String result = null;

        result = HttpsUtil.httpsRequestToString(url, "POST", xml);


        String reg = "<prepay_id><!\\[CDATA\\[(\\w+)\\]\\]></prepay_id>";

        Pattern pattern = Pattern.compile(reg);

        Matcher matcher = pattern.matcher(result);

        String prepayId = "";

        while (matcher.find()) {

            prepayId = matcher.group(1);

            System.out.println("预支付ID：" + prepayId);
        }
        Date beijingDate = Calendar.getInstance(Locale.CHINA).getTime();
        String  datassss=String.valueOf(beijingDate.getTime() / 1000);
        String  nonceStrss =createNonceStr();
      //appId, timeStamp, nonceStr, package, signType
        //paySign=MD5(appId=${appid}&nonceStr=${nonceStr}&package=prepay_id=${prepay_id}&signType=MD5&timeStamp=${timeStamp}&key=${key}).toString().toUpperCase();
        String stringAs="appId="+appids+"&nonceStr="+nonceStrss+"&package=prepay_id="+prepayId+"&signType=MD5&timeStamp="+datassss+"&key="+MerchantKey;
        System.out.println(stringAs);
        String dd = null;
        try {
            dd = MD5(stringAs).toUpperCase();
        } catch (Exception e) {
            e.printStackTrace();
        }

        returnMap.put("paySignss",dd);
        returnMap.put("appids",appids);
        returnMap.put("timestampss", datassss);
        returnMap.put("nonceStrss", nonceStrss);
        returnMap.put("packagess", "prepay_id=" + prepayId);
        returnMap.put("signTypess", "MD5");

        return returnMap;
    }*/

    /**
     * 生成 MD5
     *
     * @param data 待处理数据
     * @return MD5结果
     */
    public static String MD5(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }

/**
 * 生成随机数
 * <p>算法参考：https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3</p>
 * @return 随机数字符串

 */

    public static String createNonceStr() {
        SecureRandom random = new SecureRandom();
        int randomNum = random.nextInt();
        return Integer.toString(randomNum);
    }

/**
 * 生成签名，用于在微信支付前，获取预支付时候需要使用的参数sign
 * <p>算法参考：https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3</p>
 * @param params 需要发送的所有数据设置为的Map
 * @return 签名sign
 */

    public  String createSign(TreeMap<String, String> params) {
        String signValue = "";
        String stringSignTemp = "";

        String stringA = "";
        //获得stringA
        Set<String> keys = params.keySet();
        for (String key : keys) {
            stringA += (key + "=" + params.get(key) + "&");
        }
        stringA = stringA.substring(0, stringA.length() - 1);
        //获得stringSignTemp
        stringSignTemp = stringA + "&key=" + MerchantKey;
        //获得signValue
        signValue = encryptByMD5(stringSignTemp).toUpperCase();
        System.out.println("预支付签名：" + signValue);
        return signValue;
    }
    
   /* public  String createSign1(TreeMap<Object, Object> params) {
        String signValue = "";
        String stringSignTemp = "";

        String stringA = "";
        //获得stringA
        Set<String> keys = params.keySet();
        for (String key : keys) {
            stringA += (key + "=" + params.get(key) + "&");
        }
        stringA = stringA.substring(0, stringA.length() - 1);
        //获得stringSignTemp
        stringSignTemp = stringA + "&key=" + MerchantKey;
        //获得signValue
        signValue = encryptByMD5(stringSignTemp).toUpperCase();
        System.out.println("预支付签名：" + signValue);
        return signValue;
    }*/

/**
 * MD5加密
 * @param sourceStr
 * @return
 */

    public static String encryptByMD5(String sourceStr) {
        String result = "";
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(sourceStr.getBytes("UTF-8"));
            byte b[] = md.digest();
            int i;
            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                i += 256;
                if (i < 16)
                buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            result = buf.toString();
        } catch (NoSuchAlgorithmException e) {
            System.out.println(e);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }


    public static String  GetResponse(String path,String Info,String xml) throws IOException
    {


        //1, 得到URL对象
        URL url = new URL(path);

        //2, 打开连接
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        //3, 设置提交类型
        conn.setRequestMethod(Info);
        conn.setRequestProperty("Content-Type", "text/xml");

        //4, 设置允许写出数据,默认是不允许 false
        conn.setDoOutput(true);
        conn.setDoInput(true);//当前的连接可以从服务器读取内容, 默认是true

        //5, 获取向服务器写出数据的流
        OutputStream os = conn.getOutputStream();
        //参数是键值队  , 不以"?"开始
        os.write(xml.getBytes());
        //os.write("googleTokenKey=&username=admin&password=5df5c29ae86331e1b5b526ad90d767e4".getBytes());
        os.flush();
        //6, 获取响应的数据
        //得到服务器写回的响应数据
        BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream(),"utf-8"));
        String str = br.readLine();
        //System.out.println("响应内容为:  " + str);

        return  str;
    }
    public  String creatPostAndTransData(String path,String Info,String xml) {
        String urlStr = "";
        String line = "";
        StringBuffer resultSting = new StringBuffer();
        try {
            //urlStr,写在了配置文件中,直接进行获取
            urlStr = path;
            //声明URL
            URL url = new URL(urlStr);
            //1.创建链接
            URLConnection con = url.openConnection();
            //2.封装报文传输进行传输
            //调用getXmlInfo(Map<String, Object> dataMap)进行报文的封装
            String xmlInfo = xml;
            byte[] xmlData = xmlInfo.getBytes();
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setUseCaches(false);
            con.setRequestProperty("Pragma:", "no-cache");
            con.setRequestProperty("Cache-Control", "no-cache");
            con.setRequestProperty("Content-Type", "text/xml");
            con.setRequestProperty("Content-length",String.valueOf(xmlData.length));
            OutputStreamWriter out = new OutputStreamWriter(
                    con.getOutputStream());
            System.out.println(">>>>>>>>>>接口地址为urlStr=" + urlStr);
            System.out.println(">>>>>>>>>>传入的报文xmlInfo=" + xmlInfo);
            out.write(new String(xmlInfo.getBytes("ISO-8859-1")));
            out.flush();
            out.close();
            //3.获取返回报文
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    con.getInputStream()));
            //对返回值报文进行打印
            for (line = br.readLine(); line != null; line = br.readLine()) {
                //对返回的报文进行结果判断<RspCode>0000</RspCode>
                System.out.println(">>>>>>>>>>>>>>>>>>>返回的结果报文内容为:---------"+line);
                //对返回的报文进行拼接,然后返回给业务层,在业务层进行判断
                resultSting.append(line);
            }
            return resultSting.toString();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resultSting.toString();
    }



}
